package com.yun.zf.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yun.zf.admin.mapper.ZfCustomerMapper;
import com.yun.zf.admin.mapper.ZfCustomerRequirementMapper;
import com.yun.zf.admin.service.ZfCustomerAgentService;
import com.yun.zf.admin.service.ZfCustomerRequirementService;
import com.yun.zf.admin.service.ZfCustomerService;
import com.yun.zf.common.admin.dto.customer.CustomerInfoDto;
import com.yun.zf.common.admin.model.customer.CustomerAgentInfoMo;
import com.yun.zf.common.admin.model.customer.CustomerBasicMo;
import com.yun.zf.common.admin.model.customer.CustomerDetailInfoMo;
import com.yun.zf.common.admin.model.customer.CustomerReqMo;
import com.yun.zf.common.admin.model.search.CustomerIndexKey;
import com.yun.zf.common.admin.model.search.CustomerSearchMo;
import com.yun.zf.common.app.domain.ZfCustomer;
import com.yun.zf.common.app.domain.ZfCustomerRequirement;
import com.yun.zf.common.constant.Constants;
import com.yun.zf.common.esIndex.CustomerIndexTemplate;
import com.yun.zf.common.esIndex.CustomerRequirementTemplate;
import com.yun.zf.common.esRes.CustomerIndexResMo;
import com.yun.zf.common.mapstruct.admin.CustomerMapper;
import com.yun.zf.system.security.utils.SecurityUtils;
import com.yun.zf.system.utils.EsRestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 客户资源需求表 服务实现类
 * </p>
 *
 * @author cj
 * @since 2021-03-30
 */
@Service
@Slf4j
public class ZfCustomerRequirementServiceImpl extends ServiceImpl<ZfCustomerRequirementMapper, ZfCustomerRequirement> implements ZfCustomerRequirementService {

    @Autowired
    private EsRestUtil esRestUtil;
    @Autowired
    private ZfCustomerService customerService;
    @Autowired
    private ZfCustomerAgentService customerAgentService;
    @Autowired
    private ZfCustomerMapper customerMapper;

    /**
     * 录入客户需求
     *
     * @return
     */
    @Override
    public int addRequirement(CustomerReqMo req, Long proCode, Long cityCode) {
        ZfCustomerRequirement requirement = CustomerMapper.INSTANCE.moToRequirement(req);
        requirement.setCityCode(cityCode);
        requirement.setProvinceCode(proCode);
        requirement.setCreateTime(new Date());
        requirement.setEntrustDate(new Date());
        String unit = "元";
        Integer[] st1 = new Integer[]{4, 5, 6, 7};
        for (int s : st1) {
            if (req.getDemandType() == s) {
                unit = "万元";
            }
        }
        requirement.setUnit(unit);
        int count = baseMapper.insert(requirement);
        return count;
    }

    /**
     * 修改补充客户资源需求信息
     *
     * @return
     */
    @Override
    public int motifyRequirement(CustomerReqMo req, Long proCode, Long cityCode) {
        QueryWrapper<ZfCustomerRequirement> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ZfCustomerRequirement::getId, req.getId())
                .eq(ZfCustomerRequirement::getCityCode, cityCode).eq(ZfCustomerRequirement::getProvinceCode, proCode);
        ZfCustomerRequirement requirement = baseMapper.selectOne(wrapper);
        String unit = "元";
        Integer[] st1 = new Integer[]{4, 5, 6, 7};
        for (int s : st1) {
            if (req.getDemandType() == s) {
                unit = "万元";
            }
        }
        req.setUnit(unit);
        BeanUtil.copyProperties(req, requirement, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        return baseMapper.update(requirement, wrapper);
    }


    @Override
    public List<CustomerInfoDto> findRequirements(Long proCode, Long cityCode, Long customerId) {
        return baseMapper.getReqTempt(proCode, cityCode, customerId);
    }

    @Override
    public CustomerReqMo getRequirement(Long proCode, Long cityCode, Long requirementId) {
        return baseMapper.requirement(proCode, cityCode, requirementId);
    }

    @Override
    public Map<String, Object> searchCustomer(CustomerSearchMo customerSearchMo, Long proCode, Long cityCode) {
        String[] fields = new String[]{CustomerIndexKey.CUSTOMERID, CustomerIndexKey.PROVINCECODE, CustomerIndexKey.CITYCODE};
        //1 、 构建搜索条件
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        // 城市代码必传
        queryBuilder.must(QueryBuilders.termQuery(CustomerIndexKey.CITYCODE, cityCode));
        if ("privately".equals(customerSearchMo.getSpace())){
            queryBuilder.must(QueryBuilders.termQuery(CustomerIndexKey.AGENTNO, SecurityUtils.getLoginUser().getAgentNo()));
        }else {
            queryBuilder.must(QueryBuilders.termQuery(CustomerIndexKey.SPACE, customerSearchMo.getSpace()));
        }

        // 搜索关键字不为空，就匹配多个字段
        if (StringUtils.isNotBlank(customerSearchMo.getKey())) {
            //设置字段权重
            Map<String, Float> keyfields = new HashMap<>();
            keyfields.put("phone", 5f); // 手机号码
            keyfields.put("name", 5f); // 客户名称
            //查询
            MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder(customerSearchMo.getKey(), "phone", "name").fields(keyfields);
            queryBuilder.must(multiMatchQueryBuilder);
        }

        // 基本需求嵌套查询
        NestedQueryBuilder basicNested = null;
        BoolQueryBuilder basicBoolQuery = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(customerSearchMo.getDemandType())&&!"BX".equals(customerSearchMo.getDemandType())) {
            basicBoolQuery.must(QueryBuilders.termQuery(CustomerIndexKey.DEMANDTYPE, customerSearchMo.getDemandType()));
        }
        // 匹配预算
        if (StringUtils.isNotBlank(customerSearchMo.getBudget())&&!"BX".equals(customerSearchMo.getBudget())) {
            int minBudget = Integer.parseInt(customerSearchMo.getBudget().split("-")[0]);
            int maxBudget = Integer.parseInt(customerSearchMo.getBudget().split("-")[1]);
            basicBoolQuery.must(QueryBuilders.rangeQuery(CustomerIndexKey.BUDGETRANGE).gte(minBudget).lte(maxBudget));
        }
        // 单位
        if (StringUtils.isNotBlank(customerSearchMo.getDemandType())) {
            String unit = "元";
            String[] st1 = new String[]{"4", "5", "6", "7"};
            for (String s : st1) {
                if (customerSearchMo.getDemandType().equals(s)) {
                    unit = "万元";
                }
            }

            basicBoolQuery.must(QueryBuilders.termQuery(CustomerIndexKey.UNIT, unit));
        }

        // 匹配面积
        if (StringUtils.isNotBlank(customerSearchMo.getArea())&&!"BX".equals(customerSearchMo.getArea())) {
            String minArea = customerSearchMo.getArea().split("-")[0];
            String maxArea = customerSearchMo.getArea().split("-")[1];
            basicBoolQuery.filter(QueryBuilders.rangeQuery(CustomerIndexKey.AREARANGE).gte(minArea).lte(maxArea));
        }
        if (StringUtils.isNotBlank(customerSearchMo.getFixtures())&&!"BX".equals(customerSearchMo.getFixtures())) {
            String[] fix = customerSearchMo.getFixtures().split(",");
            basicBoolQuery.must(QueryBuilders.termsQuery(CustomerIndexKey.FIXTURES, fix));
        }
        // 匹配居室
        if (StringUtils.isNotBlank(customerSearchMo.getBedrooms())&&!"BX".equals(customerSearchMo.getBedrooms())) {
            String minRoom = customerSearchMo.getBedrooms().split("-")[0];
            String maxRoom = customerSearchMo.getBedrooms().split("-")[1];
            basicBoolQuery.filter(QueryBuilders.rangeQuery(CustomerIndexKey.BEDROOMSRANGE).gte(minRoom).lte(maxRoom));
        }
        // 匹配楼层
        if (StringUtils.isNotBlank(customerSearchMo.getFloor())&&!"BX".equals(customerSearchMo.getFloor())) {
            String minFloor = customerSearchMo.getFloor().split("-")[0];
            String maxFloor = customerSearchMo.getFloor().split("-")[1];
            basicBoolQuery.filter(QueryBuilders.rangeQuery(CustomerIndexKey.FLOORRANGE).gte(minFloor).lte(maxFloor));
        }

        if (StringUtils.isNotBlank(customerSearchMo.getRentType())&&!"BX".equals(customerSearchMo.getRentType())) {
            basicBoolQuery.must(QueryBuilders.termQuery(CustomerIndexKey.RENTTYPE, customerSearchMo.getRentType()));
        }
        if (StringUtils.isNotBlank(customerSearchMo.getSchool())&&!"BX".equals(customerSearchMo.getSchool())) {
            String[] schools = customerSearchMo.getSchool().split(",");
            basicBoolQuery.must(QueryBuilders.termsQuery(CustomerIndexKey.SCHOOL, schools));
        }
        if (StringUtils.isNotBlank(customerSearchMo.getHospital())&&!"BX".equals(customerSearchMo.getHospital())) {
            String[] hospitals = customerSearchMo.getHospital().split(",");
            basicBoolQuery.must(QueryBuilders.termsQuery(CustomerIndexKey.HOSPITAL, hospitals));
        }

        //创建需求基本信息嵌套查询对象 , 如果嵌套查询，要判断子对象是否为空，否则查询不到
        if (basicBoolQuery.filter() != null && basicBoolQuery.filter().size() > 0) {
            basicNested = QueryBuilders.nestedQuery(CustomerIndexKey.BASICPATH, basicBoolQuery, ScoreMode.None);
        }


        //公交站嵌套类型查询,如果需要，线路必选，站点非必选，所以将线路放在下面，不为空就创建busNested 对象
        NestedQueryBuilder busNested = null;
        BoolQueryBuilder busQueryBuilder = QueryBuilders.boolQuery();

        if (StringUtils.isNotBlank(customerSearchMo.getStop())&&!"BX".equals(customerSearchMo.getStop())) {
            busQueryBuilder.must(QueryBuilders.termsQuery(CustomerIndexKey.BUSSTOPSPATH, JSONObject.parseArray(customerSearchMo.getStop())));
        }
        if (StringUtils.isNotBlank(customerSearchMo.getBus())&&!"BX".equals(customerSearchMo.getBus())) {
            busQueryBuilder.filter(QueryBuilders.matchQuery(CustomerIndexKey.BUSWAYPATH, customerSearchMo.getBus()));
            //创建公交站嵌套查询对象
            busNested = QueryBuilders.nestedQuery(CustomerIndexKey.BUSPATH, busQueryBuilder, ScoreMode.None);
        }


        // 创建地铁嵌套对象 ，如果选择了地铁筛选地铁线必选 ，站点非必选，所以将线路放在下面不为空，则创建subwayNested 对象
        NestedQueryBuilder subwayNested = null;
        BoolQueryBuilder subwayQueryBuilder = QueryBuilders.boolQuery();

        if (StringUtils.isNotBlank(customerSearchMo.getStations())) {
            subwayQueryBuilder.must(QueryBuilders.termsQuery(CustomerIndexKey.SUBWAYSTATIONSPATH, JSONObject.parseArray(customerSearchMo.getStations())));
        }
        if (StringUtils.isNotBlank(customerSearchMo.getSubway())) {
            subwayQueryBuilder.filter(QueryBuilders.matchQuery(CustomerIndexKey.SUBWAYPATH, customerSearchMo.getSubway()));
            //创建地铁嵌套查询对象
            subwayNested = QueryBuilders.nestedQuery(CustomerIndexKey.SUBPATH, subwayQueryBuilder, ScoreMode.None);
        }
        if (busNested != null) {
            queryBuilder.must(busNested);
        }
        if (subwayNested != null) {
            queryBuilder.must(subwayNested);
        }
        if (basicNested != null) {
            queryBuilder.must(basicNested);
        }
        searchQueryBuilder.withQuery(queryBuilder).withFields(fields);
        try {
            Map<String, Object> customerData = esRestUtil.searchDataPage(Constants.ES_CUSTOMER_INDEX, customerSearchMo.getCurrent(), customerSearchMo.getPageSize(), CustomerIndexResMo.class, searchQueryBuilder);
            return customerData;
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 获取详情信息
     *
     * @param customerId
     * @param provCode
     * @param cityCode
     */
    @Override
    public CustomerDetailInfoMo getCustomerDetailInfo(Long customerId, Long provCode, Long cityCode) {
        //1、获取客户基本信息
        CustomerBasicMo customer = customerService.getBasicInfo(provCode, cityCode, customerId);
        customer.setPhone(customer.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"));
        // 2、获取经纪人列表信息
        List<CustomerAgentInfoMo> infoMos = customerAgentService.getCustomerInfo(provCode, cityCode, customerId);
        //2、获取客户需求信息
        List<CustomerReqMo> requirements = baseMapper.getRequirement(provCode, cityCode, customerId);
        CustomerDetailInfoMo detailInfoMo = new CustomerDetailInfoMo();
        detailInfoMo.setRequirementList(requirements);
        detailInfoMo.setAgentInfoMos(infoMos);
        detailInfoMo.setBasicMo(customer);
        int agentNo = SecurityUtils.getLoginUser().getAgentNo();
        int  count =  customerAgentService.checkAuthorize(customerId, agentNo, provCode, cityCode);
        if (count>0){
            detailInfoMo.setIsProtect("Y");
        }else {
            detailInfoMo.setIsProtect("N");
        }
        return detailInfoMo;
    }

    @Override
    public void pushCustomer(Long proCode, Long cityCode, Long customerId) {
        //1, 查询客户基础信息
        ZfCustomer customer = customerService.getCustomerInfo(proCode, cityCode, customerId);
        List<CustomerInfoDto> requirements = baseMapper.getReqTempt(proCode, cityCode, customerId);
        CustomerIndexTemplate customerIndexTemplate = new CustomerIndexTemplate();
        customerIndexTemplate.setCustomerId(customer.getId().toString());
        customerIndexTemplate.setCityCode(customer.getCityCode());
        customerIndexTemplate.setProvinceCode(customer.getProvinceCode());
        customerIndexTemplate.setPhone(customer.getPhone());
        customerIndexTemplate.setStatus(customer.getStatus());
        customerIndexTemplate.setName(customer.getName());
        int agentNo = SecurityUtils.getLoginUser().getAgentNo();
        customerIndexTemplate.setAgentNo(agentNo);
        List<CustomerRequirementTemplate> list = CustomerMapper.INSTANCE.requirementToIndexTemp(requirements);
        customerIndexTemplate.setRequirements(list);
        customerIndexTemplate.setSpace("privately");
        try {

            String res = esRestUtil.addDataRest(customerIndexTemplate, Constants.ES_CUSTOMER_INDEX, customerId.toString());
            log.info("客源推送结果-------" + res);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void pushPlatform(Long proCode, Long cityCode, String customerId) {
        // 修改数据状态
        customerMapper.pushPlatform(proCode, cityCode, Long.parseLong(customerId));
        CustomerIndexTemplate template = new CustomerIndexTemplate();
        template.setSpace("platform");
        esRestUtil.updateDataById(template, Constants.ES_CUSTOMER_INDEX, customerId);

    }
}
